package jmine.tec.web.front.dispatcher.request;

import static jmine.tec.web.front.dao.BaseRequestStatus.PENDING;
import static jmine.tec.web.front.domain.BackOfficeRequestRevisionOutcome.AUTHORIZED;
import static jmine.tec.web.front.domain.BackOfficeRequestRevisionOutcome.REJECTED;
import jmine.tec.web.front.dao.BackOfficeRequestRevisionDAO;
import jmine.tec.web.front.dao.BackOfficeRequestStatusDAO;
import jmine.tec.web.front.dao.BaseRequestStatus;
import jmine.tec.web.front.domain.BackOfficeRequest;
import bancosys.tec.persist.persister.StatelessPersister;

/**
 * Lifecycle of a back office request that needs a single authorization to be sent.
 * 
 * @author lundberg
 */
public class BackOfficeRequestLifecycleSingleAuth implements BackOfficeRequestLifecycle {

    private final BackOfficeRequestStatusDAO backOfficeRequestStatusDAO;

    private final BackOfficeRequestRevisionDAO backOfficeRequestRevisionDAO;

    private final StatelessPersister persister;

    private final BackOfficeRequestSender sender;

    /**
     * Constructor
     * 
     * @param backOfficeRequestStatusDAO backOfficeRequestStatusDAO
     * @param backOfficeRequestRevisionDAO backOfficeRequestRevisionDAO
     * @param persister persister
     * @param sender sender
     */
    public BackOfficeRequestLifecycleSingleAuth(BackOfficeRequestStatusDAO backOfficeRequestStatusDAO,
            BackOfficeRequestRevisionDAO backOfficeRequestRevisionDAO, StatelessPersister persister, BackOfficeRequestSender sender) {
        super();
        this.backOfficeRequestStatusDAO = backOfficeRequestStatusDAO;
        this.backOfficeRequestRevisionDAO = backOfficeRequestRevisionDAO;
        this.persister = persister;
        this.sender = sender;
    }

    /**
     * {@inheritDoc}
     */
    public void process(BackOfficeRequest request) {
        if (!request.getStatus().isIdentifiedBy(PENDING)) {
            return;
        }
        if (this.hasRejection(request)) {
            request.setStatus(this.backOfficeRequestStatusDAO.findBySystemIdentifier(BaseRequestStatus.REJECTED));
            this.persister.save(request);
        } else if (this.hasAuthorization(request)) {
            this.sender.send(request);
            request.setStatus(this.backOfficeRequestStatusDAO.findBySystemIdentifier(BaseRequestStatus.SENT));
            this.persister.save(request);
        }
    }

    /**
     * Checks if this request has at least one revision that authorizes it's sending
     * 
     * @param request request
     * @return boolean
     */
    private boolean hasAuthorization(BackOfficeRequest request) {
        return !this.backOfficeRequestRevisionDAO.findByRequestOutcome(request, AUTHORIZED).isEmpty();
    }

    /**
     * Checks if this request has at least one revision that rejects it's sending
     * 
     * @param request request
     * @return boolean
     */
    private boolean hasRejection(BackOfficeRequest request) {
        return !this.backOfficeRequestRevisionDAO.findByRequestOutcome(request, REJECTED).isEmpty();
    }
}